package com.chaos.system.service.baidu;

import com.alibaba.fastjson.JSONObject;
import com.chaos.system.api.dto.BaiduLocationDto;
import com.chaos.system.service.third.BaiduLbThirdFeign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author Jacky Cui
 * @date 2020/3/11 11:36
 */
@Component
@Slf4j
public class BaiduLbService {
    @Value("${baidu.lbs.ak:}")
    String ak;
    @Value("${baidu.lbs.sk:}")
    String sk;

    @Autowired
    private BaiduLbThirdFeign baiduLbThirdFeign;

    public BaiduLocationDto location(String ip) {
        String sn;
        try {
            sn = sn(ip);
        } catch (UnsupportedEncodingException e) {
            log.error("百度LBS服务异常,ip: {}", ip);
            return null;
        }

        JSONObject resp = baiduLbThirdFeign.location(ak, ip, "bd09ll", sn);
        BaiduLocationDto location = new BaiduLocationDto();
        location.setAddress((String) resp.get("address"));
        location.setStatus((Integer) resp.get("status"));

        LinkedHashMap content = (LinkedHashMap) resp.get("content");
        location.setContentAddress((String) content.get("address"));

        LinkedHashMap address_detail = (LinkedHashMap) content.get("address_detail");
        location.setContentAddressDetailCity((String) address_detail.get("city"));
        location.setContentAddressDetailCityCode((Integer) address_detail.get("city_code"));
        location.setContentAddressDetailDistrict((String) address_detail.get("district"));
        location.setContentAddressDetailProvince((String) address_detail.get("province"));

        LinkedHashMap point = (LinkedHashMap) content.get("point");
        location.setPointX((String) point.get("x"));
        location.setPointY((String) point.get("y"));
        return location;
    }

    private String sn(String ip) throws UnsupportedEncodingException {
        BaiduLbSnCal snCal = new BaiduLbSnCal();

        // 计算sn跟参数对出现顺序有关，get请求请使用LinkedHashMap保存<key,value>，该方法根据key的插入顺序排序；post请使用TreeMap保存<key,value>，该方法会自动将key按照字母a-z顺序排序。所以get请求可自定义参数顺序（sn参数必须在最后）发送请求，但是post请求必须按照字母a-z顺序填充body（sn参数必须在最后）。以get请求为例：http://api.map.baidu.com/geocoder/v2/?address=百度大厦&output=json&ak=yourak，paramsMap中先放入address，再放output，然后放ak，放入顺序必须跟get请求中对应参数的出现顺序保持一致。

        Map paramsMap = new LinkedHashMap<String, String>();
        paramsMap.put("ak", ak);
        paramsMap.put("ip", ip);
        paramsMap.put("coor", "bd09ll");

        // 调用下面的toQueryString方法，对LinkedHashMap内所有value作utf8编码，拼接返回结果address=%E7%99%BE%E5%BA%A6%E5%A4%A7%E5%8E%A6
        // &output=json&ak=yourak
        String paramsStr = snCal.toQueryString(paramsMap);

        // 对paramsStr前面拼接上/geocoder/v2/?，后面直接拼接yoursk得到/geocoder/v2/?address=%E7%99%BE%E5%BA%A6%E5%A4%A7%E5%8E%A6
        // &output=json&ak=yourakyoursk
        String wholeStr = new String("/location/ip?" + paramsStr + sk);

        // 对上面wholeStr再作utf8编码
        String tempStr = URLEncoder.encode(wholeStr, "UTF-8");

        // 调用下面的MD5方法得到最后的sn签名7de5a22212ffaa9e326444c75a58f9a0
        String sn = snCal.MD5(tempStr);
        //System.out.println(sn);
        return sn;
    }
}
